import java.util.Observable;

public class SharedMemory extends Observable
{
	private static final int BUFFER_MAX = 10;
	private ProcessControlBlock my_producer;
	private ProcessControlBlock my_consumer;
	private int my_id;
	private boolean my_empty_flag;
	private boolean my_full_flag;
	private volatile int my_size;
	private volatile int[] my_buffer;
	
	public SharedMemory(final int the_id)
	{
		my_id = the_id;
		my_empty_flag = true;
		my_full_flag = false;
		my_buffer = new int[BUFFER_MAX];
		my_size = 0;
	}
	
	public int getId()
	{
		return my_id;
	}
	
	public void setConsumer(final ProcessControlBlock the_consumer)
	{
		my_consumer = the_consumer;
	}
	
	public ProcessControlBlock getConsumer()
	{
		return my_consumer;
	}
	
	public void setProducer(final ProcessControlBlock the_producer)
	{
		my_producer = the_producer;
	}
	
	public ProcessControlBlock getProducer()
	{
		return my_producer;
	}
	
	public synchronized void produce(final int the_int)
	{
		if (my_size + 1 == BUFFER_MAX)
		{
			my_full_flag = true;
		}
		else if (my_size == 1)
		{
			my_empty_flag = false;
			my_consumer.setProcessState("RUNNABLE");
		}
		
		my_buffer[my_size] = the_int;
		my_size++;
	}
	
	public int getSize()
	{
		return my_size;
	}
	
	public synchronized void consume()
	{
		if (my_size - 1 == 0)
		{
			my_empty_flag = true;
		}
		else if (my_size + 1 == BUFFER_MAX)
		{
			my_full_flag = false;
			my_producer.setProcessState("RUNNABLE");
		}
		
		my_buffer[my_size - 1] = -1;
		my_size--;
		
	}
	
	public boolean isEmpty()
	{
		return my_empty_flag;
	}
	
	public boolean isFull()
	{
		return my_full_flag;
	}
}
